<?php

namespace App\Console\Commands;

use App\Console\Commands\Support\Stub;
use Illuminate\Console\Command;
use Illuminate\Support\Str;

class MakeServiceCommand extends Command {
    /**
     * The name of argument being used.
     *
     * @var string
     */
    protected $argumentName = 'service';

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'make:service {service : service文件名}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '生成service类';

    protected $defaultNamespace = 'App\\Services';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle() {
        $contents = (new Stub($this->getStubName(), [
            'CLASS_NAMESPACE' => $this->getClassNamespace(),
            'CLASS' => $this->getClass(),
        ]))->render();
        if ($this->saveTo($contents)) {
            echo "\033[38;5;2mCreated : " . $this->getClassPath() . "/" . $this->getClass() . ".php \033[0m \n";
            exit();
        } else {
            echo "\033[38;5;1m[Error]\033[0m \n";
            exit();
        }
    }

    /**
     * Get Class path.
     *
     * @return string
     */
    public function getClassPath() {
        $path = app_path() . "/Services/";
        if (Str::contains($this->getServiceName(), '/')) {
            $class_path_arr = explode("/", $this->getServiceName());
            array_pop($class_path_arr);
            $class_path = implode("/", $class_path_arr);
        } else {
            $class_path = "";
        }
        $path .= $class_path;
        if (!is_dir($path)) {
            mkdir($path, '755');
        }
        return $path;
    }

    /**
     * Save stub to specific path.
     *
     * @param string $path
     * @param string $filename
     *
     * @return bool
     */
    public function saveTo($contents) {
        $file = $this->getClassPath() . "/" . $this->getClass() . ".php";
        if (is_file($file)) {
            echo "\033[38;5;1m[Error] : service class is exist！\033[0m \n";
            exit();
        }
        return file_put_contents($file, $contents);
    }

    /**
     * Get class name.
     *
     * @return string
     */
    public function getClass() {
        return class_basename($this->argument($this->argumentName));
    }

    /**
     * Get class namespace.
     *
     * @param \Nwidart\Modules\Module $module
     *
     * @return string
     */
    public function getClassNamespace() {
        $extra = str_replace($this->getClass(), '', $this->argument($this->argumentName));

        $extra = str_replace('/', '\\', $extra);

        $namespace = $this->defaultNamespace;

        $namespace .= '\\' . $extra;

        $namespace = str_replace('/', '\\', $namespace);

        return trim($namespace, '\\');
    }

    /**
     * @return array|string
     */
    protected function getServiceName() {
        $service = Str::studly($this->argument('service'));

        if (Str::contains(strtolower($service), 'service') === false) {
            $service .= 'Service';
        }

        return $service;
    }

    /**
     * Get the stub file name based on the options
     *
     * @return string
     */
    protected function getStubName() {
        $stub = __DIR__ . '/stubs/service.stub';

        return $stub;
    }
}
